import CryptoJS from 'crypto-browserify';
import CryptoSM from 'sm-crypto';
const Buffer = require('buffer').Buffer;
/**
 * sm2+相关的国密
 */
class SmEnDe {
    //选取sm2还是sm3
    sm2;
    sm3;
    sm4;
    constructor() {
        this.sm2 = CryptoSM.sm2;
        this.sm3 = CryptoSM.sm3;
        this.sm4 = CryptoSM.sm4;
    }
    /**
     * 获取密钥对
     * @returns 密钥对
     */
    createPairKeys() {
        const keypair = this.sm2.generateKeyPairHex();
        const publicKey = this.hexToBase64(keypair.publicKey);
        const privateKey = this.hexToBase64(keypair.privateKey);
        return { publicKey, privateKey };
    }
    /**
     * sm2加密
     * @param msgString 待加密数据
     * @param publicKey 公钥
     * @param cipherMode 密码
     * @returns 加密结果
     */
    encrypt(msgString, publicKey, cipherMode = 0) {
        if (!msgString || !publicKey) throw new Error('参数有空值');
        const publicKeyHex = this.base64ToHex(publicKey);
        let encryptData = this.sm2.doEncrypt(msgString, publicKeyHex, cipherMode); // 加密结果
        encryptData = this.hexToBase64(encryptData);
        return encryptData;
    }
    /**
     * sm2解密
     * @param encryptData 待解密数据
     * @param privateKey 私钥
     * @param cipherMode 密码
     * @returns 解密结果
     */
    decrypt(encryptData, privateKey, cipherMode = 0) {
        if (!encryptData || !privateKey) throw new Error('参数有空值');
        const privateKeyHex = this.base64ToHex(privateKey);
        const encryptDataHex = this.base64ToHex(encryptData);
        return this.sm2.doDecrypt(encryptDataHex, privateKeyHex, cipherMode); // 解密结果
    }
    /**
     * sm4加密
     * @param inArray 待加密数据
     * @param key 公钥
     * @returns 加密结果
     */
    sm4Encrypt(inArray, key) {
        let encryptData = this.sm4.encrypt(inArray, key); // 加密结果
        encryptData = this.hexToBase64(encryptData);
        return encryptData;
    }
    /**
     * sm4解密
     * @param encData 待解密数据
     * @param key 私钥
     * @returns 解密结果
     */
    sm4Decrypt(encData, key) {
        const decryptData = this.sm4.decrypt(encData, key); // 解密结果
        return this.hexToBase64(decryptData);
    }
    /**
     * 字符串哈希处理
     * @param str 字符串
     * @returns 对应的哈希
     */
    getHash(str) {
        let hashData = this.sm3(str);
        hashData = this.hexToBase64(hashData);
        return hashData;
    }
    /**
     * 文件哈希处理
     * @param msg 文件数据
     * @returns 对应的哈希
     */
    getHashForFile(msg) {
        let hashData = this.sm2.newSm3Hash(msg);
        hashData = this.hexToBase64(hashData);
        return hashData;
    }
    /**
     * 做签名
     * @param msgString 原文
     * @param privateKey 私钥
     * @param publicKey 公钥
     * @returns base64签名
     */
    doSignature(msgString, privateKey, publicKey) {
        if (!msgString || !privateKey || !publicKey) throw new Error('参数有空值');
        const privateKeyHex = this.base64ToHex(privateKey);
        const publicKeyHex = this.base64ToHex(publicKey);
        // 纯签名 + 生成椭圆曲线点 + der编解码
        const sigValueHex = this.sm2.doSignature(msgString, privateKeyHex, {
            der: true,
            hash: true,
            publicKeyHex,
        }); // 签名
        return this.hexToBase64(sigValueHex);
    }
    /**
     * 验证签名
     * @param msgString 原文
     * @param mySigValueBase64 base64签名
     * @param publicKey 公钥
     * @returns 验签结果
     */
    doVerifySignature(msgString, mySigValueBase64, publicKey) {
        const publicKeyHex = this.base64ToHex(publicKey);
        const mySigValueHex = this.base64ToHex(mySigValueBase64);
        return this.sm2.doVerifySignature(msgString, mySigValueHex, publicKeyHex, {
            der: true,
            hash: true,
            publicKeyHex,
        });
    }
    /**
     * 随机生成128bits的随机数
     * @returns 128bits的随机数
     */
    radomkey() {
        return CryptoJS.randomBytes(16);
    }
    /**
     * base64转16进制
     * @param str base64数据
     * @returns 16进制数据
     */
    base64ToHex(str) {
        return str ? Buffer(str, 'base64').toString('hex') : undefined;
    }
    /**
     * 16进制转base64
     * @param str 16进制数据
     * @returns base64数据
     */
    hexToBase64(str) {
        return str ? Buffer(str, 'hex').toString('base64') : undefined;
    }
}

export default SmEnDe;
